package com.yozinga.util;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.Log;

import com.yozinga.fragment.HomePageFragment.EvalReceiver;

public class GetAddressTask extends AsyncTask<Location, Void, String>{

	Context mContext;
	EvalReceiver mEvalReceiver;
	Double mLatitude;
	Double  mLongitude;
	public GetAddressTask(Context context,EvalReceiver evalReceiver) {
		super();
		mContext = context;
		mEvalReceiver = evalReceiver;
	}
	@Override
	protected String doInBackground(Location... params) {
		Log.i("Team","DOin Background 1");
		Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
		String adderss;
		// Get the current location from the input parameter list
		Location loc = params[0];

		// Create a list to contain the result address
		List<Address> addresses = null;
		try {

			/*
			 * Return 1 address.
			 */
			mLatitude = loc.getLatitude();
			mLongitude = loc.getLongitude();
			addresses = geocoder.getFromLocation(loc.getLatitude(),loc.getLongitude(), 1);
			Log.i("Team","DOin Background 2"+addresses);

		} 
		catch (IOException e1) 
		{
			Log.i("Team","DOin Background 3"+e1);
			Log.e("LocationSampleActivity","IO Exception in getFromLocation()");
			e1.printStackTrace();
			//return null;
		} 
		catch (IllegalArgumentException e2) 
		{
			Log.i("Team","DOin Background 4"+e2);
			// Error message to post in the log
			String errorString = "Illegal arguments " +
					Double.toString(loc.getLatitude()) +
					" , " +
					Double.toString(loc.getLongitude()) +
					" passed to address service";
			Log.e("LocationSampleActivity", errorString);
			e2.printStackTrace();
			//return null;
		}

		// If the reverse geocode returned an address
		if (addresses != null && addresses.size() > 0) {

			// Get the first address
			Address address = addresses.get(0);

			Log.i("Team","Address:"+address);

			/*
			 * Format the first line of address (if available),
			 * city, and country name.
			 */
			String addressText = String.format(
					"%s, %s, %s",
					// If there's a street address, add it
					address.getMaxAddressLineIndex() > 0 ?
							address.getAddressLine(0) : "",
							// Locality is usually a city
							address.getLocality(),
							// The country of the address
							address.getCountryName());

			String street = address.getAddressLine(0);
			String Area = address.getThoroughfare();
			String city = address.getLocality();
			String district = address.getSubAdminArea();
			String state = address.getAdminArea();
			String postal = address.getPostalCode();
			String country = address.getCountryName();

			double latitude = address.getLatitude();
			double longitude = address.getLongitude();
			adderss = address.getAddressLine(0)+","+address.getAddressLine(1)+","+address.getAddressLine(2);
			Log.i("Team","Addresssdfasdfasdf is: "+address);
			// Return the text
			return adderss;

		} 
		else
		{
			adderss = fetchCityNameUsingGoogleMap();
			return adderss;
		}
	}


	// Geocoder failed :-(
	// Our B Plan : Google Map
	private String fetchCityNameUsingGoogleMap()
	{
		String googleMapUrl = "http://maps.googleapis.com/maps/api/geocode/json?latlng=" + mLatitude + ","
				+ mLongitude + "&sensor=false&language=fr";
		// search for locality and sublocality
		String cityName = null;
		DefaultHttpClient httpClient = new DefaultHttpClient();
		try
		{
			JSONObject googleMapResponse = new JSONObject(httpClient.execute(new HttpGet(googleMapUrl),
					new BasicResponseHandler()));

			// many nested loops.. not great -> use expression instead
			// loop among all results
			JSONArray results = (JSONArray) googleMapResponse.get("results");
			for (int i = 0; i < results.length(); i++)
			{
				// loop among all addresses within this result
				JSONObject result = results.getJSONObject(i);
				if (result.has("address_components"))
				{
					JSONArray addressComponents = result.getJSONArray("address_components");
					// loop among all address component to find a 'locality' or 'sublocality'
					for (int j = 0; j < addressComponents.length(); j++)
					{
						JSONObject addressComponent = addressComponents.getJSONObject(j);
						if (result.has("types"))
						{
							JSONArray types = addressComponent.getJSONArray("types");

							for (int k = 0; k < types.length(); k++)
							{
								if ("locality".equals(types.getString(k)) && cityName == null)
								{
									if (addressComponent.has("long_name"))
									{
										cityName = addressComponent.getString("long_name");
									}
									else if (addressComponent.has("short_name"))
									{
										cityName = addressComponent.getString("short_name");
									}
								}
								if ("sublocality".equals(types.getString(k)))
								{
									if (addressComponent.has("long_name"))
									{
										cityName = addressComponent.getString("long_name");
									}
									else if (addressComponent.has("short_name"))
									{
										cityName = addressComponent.getString("short_name");
									}
								}
							}
							if (cityName != null)
							{
								return cityName;
							}
						}
					}
				}
			}
		}
		catch (Exception ignored)
		{
			ignored.printStackTrace();
		}
		return cityName;
	}
	@Override
	protected void onPostExecute(String adderss) {
		ResultReceiver receiver = mEvalReceiver;
		Bundle data = new Bundle();
		data.putSerializable("address", adderss);
		if (receiver != null) {
			receiver.send(1, data);
		}
	}


}